mirror of
https://github.com/eza-community/eza
synced 2024-09-29 20:54:59 +00:00
Merge branch 'master' of github.com:cafkafk/zetta into pr-fix-fish-completion-inode
Merge changes for testing
This commit is contained in:
commit
c1379149c1
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -57,29 +57,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exa"
|
||||
version = "0.10.1"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"datetime",
|
||||
"git2",
|
||||
"glob",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"locale",
|
||||
"log",
|
||||
"natord",
|
||||
"num_cpus",
|
||||
"number_prefix",
|
||||
"scoped_threadpool",
|
||||
"term_grid",
|
||||
"terminal_size",
|
||||
"unicode-width",
|
||||
"users",
|
||||
"zoneinfo_compiled",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
|
@ -296,6 +273,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "timeago"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ec32dde57efb15c035ac074118d7f32820451395f28cb0524a01d4e94983b26"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.2.0"
|
||||
|
@ -385,6 +368,30 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "zetta"
|
||||
version = "0.11.1"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"datetime",
|
||||
"git2",
|
||||
"glob",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"locale",
|
||||
"log",
|
||||
"natord",
|
||||
"num_cpus",
|
||||
"number_prefix",
|
||||
"scoped_threadpool",
|
||||
"term_grid",
|
||||
"terminal_size",
|
||||
"timeago",
|
||||
"unicode-width",
|
||||
"users",
|
||||
"zoneinfo_compiled",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zoneinfo_compiled"
|
||||
version = "0.5.1"
|
||||
|
|
26
Cargo.toml
26
Cargo.toml
|
@ -1,20 +1,19 @@
|
|||
[package]
|
||||
name = "exa"
|
||||
name = "zetta"
|
||||
description = "A modern replacement for ls"
|
||||
authors = ["Benjamin Sago <ogham@bsago.me>"]
|
||||
authors = ["Benjamin Sago <ogham@bsago.me>", "Denis Cornehl <denis@cornehl.org>"]
|
||||
categories = ["command-line-utilities"]
|
||||
edition = "2021"
|
||||
rust-version = "1.63.0"
|
||||
exclude = ["/devtools/*", "/Justfile", "/Vagrantfile", "/screenshots.png"]
|
||||
readme = "README.md"
|
||||
homepage = "https://the.exa.website/"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/ogham/exa"
|
||||
version = "0.10.1"
|
||||
repository = "https://github.com/syphar/zetta"
|
||||
version = "0.11.1"
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "exa"
|
||||
name = "zetta"
|
||||
|
||||
|
||||
[dependencies]
|
||||
|
@ -30,6 +29,7 @@ number_prefix = "0.4"
|
|||
scoped_threadpool = "0.1"
|
||||
term_grid = "0.2.0"
|
||||
terminal_size = "0.1.16"
|
||||
timeago = { version = "0.3.1", default-features = false }
|
||||
unicode-width = "0.1"
|
||||
zoneinfo_compiled = "0.5.1"
|
||||
|
||||
|
@ -69,15 +69,15 @@ lto = true
|
|||
license-file = [ "LICENCE", "4" ]
|
||||
depends = "$auto"
|
||||
extended-description = """
|
||||
exa is a replacement for ls written in Rust.
|
||||
zetta is a replacement for ls written in Rust.
|
||||
"""
|
||||
section = "utils"
|
||||
priority = "optional"
|
||||
assets = [
|
||||
[ "target/release/exa", "/usr/bin/exa", "0755" ],
|
||||
[ "target/release/../man/exa.1", "/usr/share/man/man1/exa.1", "0644" ],
|
||||
[ "target/release/../man/exa_colors.5", "/usr/share/man/man5/exa_colors.5", "0644" ],
|
||||
[ "completions/bash/exa", "/usr/share/bash-completion/completions/exa", "0644" ],
|
||||
[ "completions/zsh/_exa", "/usr/share/zsh/site-functions/_exa", "0644" ],
|
||||
[ "completions/fish/exa.fish", "/usr/share/fish/vendor_completions.d/exa.fish", "0644" ],
|
||||
[ "target/release/zetta", "/usr/bin/zetta", "0755" ],
|
||||
[ "target/release/../man/zetta.1", "/usr/share/man/man1/zetta.1", "0644" ],
|
||||
[ "target/release/../man/zetta_colors.5", "/usr/share/man/man5/zetta_colors.5", "0644" ],
|
||||
[ "completions/bash/zetta", "/usr/share/bash-completion/completions/zetta", "0644" ],
|
||||
[ "completions/zsh/_zetta", "/usr/share/zsh/site-functions/_zetta", "0644" ],
|
||||
[ "completions/fish/zetta.fish", "/usr/share/fish/vendor_completions.d/zetta.fish", "0644" ],
|
||||
]
|
||||
|
|
8
Justfile
8
Justfile
|
@ -98,13 +98,13 @@ all-release: build-release test-release
|
|||
# build the man pages
|
||||
@man:
|
||||
mkdir -p "${CARGO_TARGET_DIR:-target}/man"
|
||||
pandoc --standalone -f markdown -t man man/exa.1.md > "${CARGO_TARGET_DIR:-target}/man/exa.1"
|
||||
pandoc --standalone -f markdown -t man man/exa_colors.5.md > "${CARGO_TARGET_DIR:-target}/man/exa_colors.5"
|
||||
pandoc --standalone -f markdown -t man man/zetta.1.md > "${CARGO_TARGET_DIR:-target}/man/zetta.1"
|
||||
pandoc --standalone -f markdown -t man man/zetta_colors.5.md > "${CARGO_TARGET_DIR:-target}/man/zetta_colors.5"
|
||||
|
||||
# build and preview the main man page (exa.1)
|
||||
@man-1-preview: man
|
||||
man "${CARGO_TARGET_DIR:-target}/man/exa.1"
|
||||
man "${CARGO_TARGET_DIR:-target}/man/zetta.1"
|
||||
|
||||
# build and preview the colour configuration man page (exa_colors.5)
|
||||
@man-5-preview: man
|
||||
man "${CARGO_TARGET_DIR:-target}/man/exa_colors.5"
|
||||
man "${CARGO_TARGET_DIR:-target}/man/zetta_colors.5"
|
||||
|
|
192
README.md
192
README.md
|
@ -1,26 +1,27 @@
|
|||
<div align="center">
|
||||
|
||||
# exa
|
||||
# zetta
|
||||
|
||||
[exa](https://the.exa.website/) is a modern replacement for _ls_.
|
||||
zetta builds on the awesome foundation of [exa](https://the.exa.website/) so we
|
||||
can add more features. When exa becomes maintained again, features could be
|
||||
merged back.
|
||||
|
||||
**README Sections:** [Options](#options) — [Installation](#installation) — [Development](#development)
|
||||
For simplicity, only installation method for now is `cargo install`.
|
||||
|
||||
**this readme will be extended again, pending some rewrites / updates.**
|
||||
|
||||
[![Unit tests](https://github.com/ogham/exa/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/ogham/exa/actions/workflows/unit-tests.yml)
|
||||
[![Say thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/ogham%40bsago.me)
|
||||
</div>
|
||||
|
||||
![Screenshots of exa](screenshots.png)
|
||||
![Screenshots of zetta](screenshots.png)
|
||||
|
||||
---
|
||||
|
||||
**exa** is a modern replacement for the venerable file-listing command-line program `ls` that ships with Unix and Linux operating systems, giving it more features and better defaults.
|
||||
**zetta** is a modern replacement for the venerable file-listing command-line program `ls` that ships with Unix and Linux operating systems, giving it more features and better defaults.
|
||||
It uses colours to distinguish file types and metadata.
|
||||
It knows about symlinks, extended attributes, and Git.
|
||||
And it’s **small**, **fast**, and just **one single binary**.
|
||||
|
||||
By deliberately making some decisions differently, exa attempts to be a more featureful, more user-friendly version of `ls`.
|
||||
For more information, see [exa’s website](https://the.exa.website/).
|
||||
By deliberately making some decisions differently, zetta attempts to be a more featureful, more user-friendly version of `ls`.
|
||||
|
||||
|
||||
---
|
||||
|
@ -29,7 +30,7 @@ For more information, see [exa’s website](https://the.exa.website/).
|
|||
<h1>Command-line options</h1>
|
||||
</a>
|
||||
|
||||
exa’s options are almost, but not quite, entirely unlike `ls`’s.
|
||||
zetta’s options are almost, but not quite, entirely unlike `ls`’s.
|
||||
|
||||
### Display options
|
||||
|
||||
|
@ -89,7 +90,7 @@ Some of the options accept parameters:
|
|||
- Valid **--color** options are **always**, **automatic**, and **never**.
|
||||
- Valid sort fields are **accessed**, **changed**, **created**, **extension**, **Extension**, **inode**, **modified**, **name**, **Name**, **size**, **type**, and **none**. Fields starting with a capital letter sort uppercase before lowercase. The modified field has the aliases **date**, **time**, and **newest**, while its reverse has the aliases **age** and **oldest**.
|
||||
- Valid time fields are **modified**, **changed**, **accessed**, and **created**.
|
||||
- Valid time styles are **default**, **iso**, **long-iso**, and **full-iso**.
|
||||
- Valid time styles are **default**, **iso**, **long-iso**, **full-iso**, and **relative**.
|
||||
|
||||
|
||||
---
|
||||
|
@ -98,175 +99,14 @@ Some of the options accept parameters:
|
|||
<h1>Installation</h1>
|
||||
</a>
|
||||
|
||||
exa is available for macOS and Linux.
|
||||
More information on how to install exa is available on [the Installation page](https://the.exa.website/install).
|
||||
|
||||
### Alpine Linux
|
||||
|
||||
On Alpine Linux, [enable community repository](https://wiki.alpinelinux.org/wiki/Enable_Community_Repository) and install the [`exa`](https://pkgs.alpinelinux.org/package/edge/community/x86_64/exa) package.
|
||||
|
||||
apk add exa
|
||||
|
||||
### Arch Linux
|
||||
|
||||
On Arch, install the [`exa`](https://www.archlinux.org/packages/community/x86_64/exa/) package.
|
||||
|
||||
pacman -S exa
|
||||
|
||||
### Android / Termux
|
||||
|
||||
On Android / Termux, install the [`exa`](https://github.com/termux/termux-packages/tree/master/packages/exa) package.
|
||||
|
||||
pkg install exa
|
||||
|
||||
### Debian
|
||||
|
||||
On Debian, install the [`exa`](https://packages.debian.org/stable/exa) package.
|
||||
|
||||
apt install exa
|
||||
|
||||
### Fedora
|
||||
|
||||
On Fedora, install the [`exa`](https://src.fedoraproject.org/modules/exa) package.
|
||||
|
||||
dnf install exa
|
||||
|
||||
### Gentoo
|
||||
|
||||
On Gentoo, install the [`sys-apps/exa`](https://packages.gentoo.org/packages/sys-apps/exa) package.
|
||||
|
||||
emerge sys-apps/exa
|
||||
|
||||
### Homebrew
|
||||
|
||||
If you’re using [Homebrew](https://brew.sh/) on macOS, install the [`exa`](http://formulae.brew.sh/formula/exa) formula.
|
||||
|
||||
brew install exa
|
||||
|
||||
### MacPorts
|
||||
|
||||
If you're using [MacPorts](https://www.macports.org/) on macOS, install the [`exa`](https://ports.macports.org/port/exa/summary) port.
|
||||
|
||||
port install exa
|
||||
|
||||
### Nix
|
||||
|
||||
On nixOS, install the [`exa`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/exa/default.nix) package.
|
||||
|
||||
nix-env -i exa
|
||||
|
||||
### openSUSE
|
||||
|
||||
On openSUSE, install the [`exa`](https://software.opensuse.org/package/exa) package.
|
||||
|
||||
zypper install exa
|
||||
|
||||
### Ubuntu
|
||||
|
||||
On Ubuntu 20.10 (Groovy Gorilla) and later, install the [`exa`](https://packages.ubuntu.com/jammy/exa) package.
|
||||
|
||||
sudo apt install exa
|
||||
|
||||
### Void Linux
|
||||
|
||||
On Void Linux, install the [`exa`](https://github.com/void-linux/void-packages/blob/master/srcpkgs/exa/template) package.
|
||||
|
||||
xbps-install -S exa
|
||||
|
||||
### Manual installation from GitHub
|
||||
|
||||
Compiled binary versions of exa are uploaded to GitHub when a release is made.
|
||||
You can install exa manually by [downloading a release](https://github.com/ogham/exa/releases), extracting it, and copying the binary to a directory in your `$PATH`, such as `/usr/local/bin`.
|
||||
|
||||
For more information, see the [Manual Installation page](https://the.exa.website/install/linux#manual).
|
||||
zetta is available for macOS and Linux.
|
||||
|
||||
### Cargo
|
||||
|
||||
If you already have a Rust environment set up, you can use the `cargo install` command:
|
||||
|
||||
cargo install exa
|
||||
cargo install zetta
|
||||
|
||||
Cargo will build the `exa` binary and place it in `$HOME/.cargo`.
|
||||
Cargo will build the `zetta` binary and place it in `$HOME/.cargo`.
|
||||
|
||||
To build without Git support, run `cargo install --no-default-features exa` is also available, if the requisite dependencies are not installed.
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a id="development">
|
||||
<h1>Development
|
||||
|
||||
<a href="https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html">
|
||||
<img src="https://img.shields.io/badge/rustc-1.63.0+-lightgray.svg" alt="Rust 1.63.0+" />
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/ogham/exa/blob/master/LICENCE">
|
||||
<img src="https://img.shields.io/badge/licence-MIT-green" alt="MIT Licence" />
|
||||
</a>
|
||||
</h1></a>
|
||||
|
||||
exa is written in [Rust](https://www.rust-lang.org/).
|
||||
You will need rustc version 1.56.1 or higher.
|
||||
The recommended way to install Rust for development is from the [official download page](https://www.rust-lang.org/tools/install), using rustup.
|
||||
|
||||
Once Rust is installed, you can compile exa with Cargo:
|
||||
|
||||
cargo build
|
||||
cargo test
|
||||
|
||||
- The [just](https://github.com/casey/just) command runner can be used to run some helpful development commands, in a manner similar to `make`.
|
||||
Run `just --list` to get an overview of what’s available.
|
||||
|
||||
- If you are compiling a copy for yourself, be sure to run `cargo build --release` or `just build-release` to benefit from release-mode optimisations.
|
||||
Copy the resulting binary, which will be in the `target/release` directory, into a folder in your `$PATH`.
|
||||
`/usr/local/bin` is usually a good choice.
|
||||
|
||||
- To compile and install the manual pages, you will need [pandoc](https://pandoc.org/).
|
||||
The `just man` command will compile the Markdown into manual pages, which it will place in the `target/man` directory.
|
||||
To use them, copy them into a directory that `man` will read.
|
||||
`/usr/local/share/man` is usually a good choice.
|
||||
|
||||
- exa depends on [libgit2](https://github.com/rust-lang/git2-rs) for certain features.
|
||||
If you’re unable to compile libgit2, you can opt out of Git support by running `cargo build --no-default-features`.
|
||||
|
||||
- If you intend to compile for musl, you will need to use the flag `vendored-openssl` if you want to get the Git feature working.
|
||||
The full command is `cargo build --release --target=x86_64-unknown-linux-musl --features vendored-openssl,git`.
|
||||
|
||||
For more information, see the [Building from Source page](https://the.exa.website/install/source).
|
||||
|
||||
|
||||
### Testing with Vagrant
|
||||
|
||||
exa uses [Vagrant][] to configure virtual machines for testing.
|
||||
|
||||
Programs such as exa that are basically interfaces to the system are [notoriously difficult to test][testing].
|
||||
Although the internal components have unit tests, it’s impossible to do a complete end-to-end test without mandating the current user’s name, the time zone, the locale, and directory structure to test.
|
||||
(And yes, these tests are worth doing. I have missed an edge case on many an occasion.)
|
||||
|
||||
The initial attempt to solve the problem was just to create a directory of “awkward” test cases, run exa on it, and make sure it produced the correct output.
|
||||
But even this output would change if, say, the user’s locale formats dates in a different way.
|
||||
These can be mocked inside the code, but at the cost of making that code more complicated to read and understand.
|
||||
|
||||
An alternative solution is to fake *everything*: create a virtual machine with a known state and run the tests on *that*.
|
||||
This is what Vagrant does.
|
||||
Although it takes a while to download and set up, it gives everyone the same development environment to test for any obvious regressions.
|
||||
|
||||
[Vagrant]: https://www.vagrantup.com/
|
||||
[testing]: https://eev.ee/blog/2016/08/22/testing-for-people-who-hate-testing/#troublesome-cases
|
||||
|
||||
First, initialise the VM:
|
||||
|
||||
host$ vagrant up
|
||||
|
||||
The first command downloads the virtual machine image, and then runs our provisioning script, which installs Rust and exa’s build-time dependencies, configures the environment, and generates some awkward files and folders to use as test cases.
|
||||
Once this is done, you can SSH in, and build and test:
|
||||
|
||||
host$ vagrant ssh
|
||||
vm$ cd /vagrant
|
||||
vm$ cargo build
|
||||
vm$ ./xtests/run
|
||||
All the tests passed!
|
||||
|
||||
Of course, the drawback of having a standard development environment is that you stop noticing bugs that occur outside of it.
|
||||
For this reason, Vagrant isn’t a *necessary* development step — it’s there if you’d like to use it, but exa still gets used and tested on other platforms.
|
||||
It can still be built and compiled on any target triple that it supports, VM or no VM, with `cargo build` and `cargo test`.
|
||||
To build without Git support, run `cargo install --no-default-features zetta` is also available, if the requisite dependencies are not installed.
|
||||
|
|
4
build.rs
4
build.rs
|
@ -22,8 +22,8 @@ use datetime::{LocalDateTime, ISO};
|
|||
fn main() -> io::Result<()> {
|
||||
#![allow(clippy::write_with_newline)]
|
||||
|
||||
let tagline = "exa - list files on the command-line";
|
||||
let url = "https://the.exa.website/";
|
||||
let tagline = "zetta - list files on the command-line";
|
||||
let url = "https://github.com/syphar/zetta/";
|
||||
|
||||
let ver =
|
||||
if is_debug_build() {
|
||||
|
|
|
@ -29,7 +29,7 @@ _exa()
|
|||
;;
|
||||
|
||||
--time-style)
|
||||
COMPREPLY=( $( compgen -W 'default iso long-iso full-iso --' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W 'default iso long-iso full-iso relative --' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -79,6 +79,7 @@ complete -c exa -l 'time-style' -d "How to format timestamps" -x -a "
|
|||
iso\t'Display brief ISO timestamps'
|
||||
long-iso\t'Display longer ISO timestaps, up to the minute'
|
||||
full-iso\t'Display full ISO timestamps, up to the nanosecond'
|
||||
relative\t'Display relative timestamps'
|
||||
"
|
||||
complete -c exa -l 'no-permissions' -d "Suppress the permissions field"
|
||||
complete -c exa -l 'octal-permissions' -d "List each file's permission in octal format"
|
||||
|
|
|
@ -43,7 +43,7 @@ __exa() {
|
|||
{-n,--numeric}"[List numeric user and group IDs.]" \
|
||||
{-S,--blocks}"[List each file's number of filesystem blocks]" \
|
||||
{-t,--time}="[Which time field to show]:(time field):(accessed changed created modified)" \
|
||||
--time-style="[How to format timestamps]:(time style):(default iso long-iso full-iso)" \
|
||||
--time-style="[How to format timestamps]:(time style):(default iso long-iso full-iso relative)" \
|
||||
--no-permissions"[Suppress the permissions field]" \
|
||||
--octal-permissions"[List each file's permission in octal format]" \
|
||||
--no-filesize"[Suppress the filesize field]" \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
% exa(1) v0.9.0
|
||||
% zetta(1) v0.9.0
|
||||
|
||||
<!-- This is the exa(1) man page, written in Markdown. -->
|
||||
<!-- This is the zetta(1) man page, written in Markdown. -->
|
||||
<!-- To generate the roff version, run `just man`, -->
|
||||
<!-- and the man page will appear in the ‘target’ directory. -->
|
||||
|
||||
|
@ -8,15 +8,15 @@
|
|||
NAME
|
||||
====
|
||||
|
||||
exa — a modern replacement for ls
|
||||
zetta — a modern replacement for ls
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
`exa [options] [files...]`
|
||||
`zetta [options] [files...]`
|
||||
|
||||
**exa** is a modern replacement for `ls`.
|
||||
**zetta** is a modern replacement for `ls` and a continuation of `exa`.
|
||||
It uses colours for information by default, helping you distinguish between many types of files, such as whether you are the owner, or in the owning group.
|
||||
|
||||
It also has extra features not present in the original `ls`, such as viewing the Git status for a directory, or recursing into directories with a tree view.
|
||||
|
@ -25,16 +25,16 @@ It also has extra features not present in the original `ls`, such as viewing the
|
|||
EXAMPLES
|
||||
========
|
||||
|
||||
`exa`
|
||||
`zetta`
|
||||
: Lists the contents of the current directory in a grid.
|
||||
|
||||
`exa --oneline --reverse --sort=size`
|
||||
`zetta --oneline --reverse --sort=size`
|
||||
: Displays a list of files with the largest at the top.
|
||||
|
||||
`exa --long --header --inode --git`
|
||||
`zetta --long --header --inode --git`
|
||||
: Displays a table of files with a header, showing each file’s metadata, inode, and Git status.
|
||||
|
||||
`exa --long --tree --level=3`
|
||||
`zetta --long --tree --level=3`
|
||||
: Displays a tree of files, three levels deep, as well as each file’s metadata.
|
||||
|
||||
|
||||
|
@ -104,7 +104,7 @@ Sort fields starting with a capital letter will sort uppercase before lowercase:
|
|||
`-I`, `--ignore-glob=GLOBS`
|
||||
: Glob patterns, pipe-separated, of files to ignore.
|
||||
|
||||
`--git-ignore` [if exa was built with git support]
|
||||
`--git-ignore` [if zetta was built with git support]
|
||||
: Do not list files that are ignored by Git.
|
||||
|
||||
`--group-directories-first`
|
||||
|
@ -157,7 +157,7 @@ These options are available when running with `--long` (`-l`):
|
|||
`--time-style=STYLE`
|
||||
: How to format timestamps.
|
||||
|
||||
: Valid timestamp styles are ‘`default`’, ‘`iso`’, ‘`long-iso`’, and ‘`full-iso`’.
|
||||
: Valid timestamp styles are ‘`default`’, ‘`iso`’, ‘`long-iso`’, ‘`full-iso`’, and ‘`relative`’.
|
||||
|
||||
`-u`, `--accessed`
|
||||
: Use the accessed timestamp field.
|
||||
|
@ -180,7 +180,7 @@ These options are available when running with `--long` (`-l`):
|
|||
`-@`, `--extended`
|
||||
: List each file’s extended attributes and sizes.
|
||||
|
||||
`--git` [if exa was built with git support]
|
||||
`--git` [if zetta was built with git support]
|
||||
: List each file’s Git status, if tracked.
|
||||
|
||||
This adds a two-character column indicating the staged and unstaged statuses respectively. The status character can be ‘`-`’ for not modified, ‘`M`’ for a modified file, ‘`N`’ for a new file, ‘`D`’ for deleted, ‘`R`’ for renamed, ‘`T`’ for type-change, ‘`I`’ for ignored, and ‘`U`’ for conflicted.
|
||||
|
@ -191,29 +191,30 @@ Directories will be shown to have the status of their contents, which is how ‘
|
|||
ENVIRONMENT VARIABLES
|
||||
=====================
|
||||
|
||||
exa responds to the following environment variables:
|
||||
Zetta responds to the following environment variables:
|
||||
(Note: Compatibility with exa is a priority hence the variable names.)
|
||||
|
||||
## `COLUMNS`
|
||||
|
||||
Overrides the width of the terminal, in characters.
|
||||
|
||||
For example, ‘`COLUMNS=80 exa`’ will show a grid view with a maximum width of 80 characters.
|
||||
For example, ‘`COLUMNS=80 zetta`’ will show a grid view with a maximum width of 80 characters.
|
||||
|
||||
This option won’t do anything when exa’s output doesn’t wrap, such as when using the `--long` view.
|
||||
This option won’t do anything when zetta’s output doesn’t wrap, such as when using the `--long` view.
|
||||
|
||||
## `EXA_STRICT`
|
||||
|
||||
Enables _strict mode_, which will make exa error when two command-line options are incompatible.
|
||||
Enables _strict mode_, which will make zetta error when two command-line options are incompatible.
|
||||
|
||||
Usually, options can override each other going right-to-left on the command line, so that exa can be given aliases: creating an alias ‘`exa=exa --sort=ext`’ then running ‘`exa --sort=size`’ with that alias will run ‘`exa --sort=ext --sort=size`’, and the sorting specified by the user will override the sorting specified by the alias.
|
||||
Usually, options can override each other going right-to-left on the command line, so that zetta can be given aliases: creating an alias ‘`zetta=zetta --sort=ext`’ then running ‘`zetta --sort=size`’ with that alias will run ‘`zetta --sort=ext --sort=size`’, and the sorting specified by the user will override the sorting specified by the alias.
|
||||
|
||||
In strict mode, the two options will not co-operate, and exa will error.
|
||||
In strict mode, the two options will not co-operate, and zetta will error.
|
||||
|
||||
This option is intended for use with automated scripts and other situations where you want to be certain you’re typing in the right command.
|
||||
|
||||
## `EXA_GRID_ROWS`
|
||||
|
||||
Limits the grid-details view (‘`exa --grid --long`’) so it’s only activated when at least the given number of rows of output would be generated.
|
||||
Limits the grid-details view (‘`zetta --grid --long`’) so it’s only activated when at least the given number of rows of output would be generated.
|
||||
|
||||
With widescreen displays, it’s possible for the grid to look very wide and sparse, on just one or two lines with none of the columns lining up.
|
||||
By specifying a minimum number of rows, you can only use the view if it’s going to be worth using.
|
||||
|
@ -222,7 +223,7 @@ By specifying a minimum number of rows, you can only use the view if it’s goin
|
|||
|
||||
Specifies the number of spaces to print between an icon (see the ‘`--icons`’ option) and its file name.
|
||||
|
||||
Different terminals display icons differently, as they usually take up more than one character width on screen, so there’s no “standard” number of spaces that exa can use to separate an icon from text. One space may place the icon too close to the text, and two spaces may place it too far away. So the choice is left up to the user to configure depending on their terminal emulator.
|
||||
Different terminals display icons differently, as they usually take up more than one character width on screen, so there’s no “standard” number of spaces that zetta can use to separate an icon from text. One space may place the icon too close to the text, and two spaces may place it too far away. So the choice is left up to the user to configure depending on their terminal emulator.
|
||||
|
||||
## `NO_COLOR`
|
||||
|
||||
|
@ -234,7 +235,7 @@ See `https://no-color.org/` for details.
|
|||
|
||||
Specifies the colour scheme used to highlight files based on their name and kind, as well as highlighting metadata and parts of the UI.
|
||||
|
||||
For more information on the format of these environment variables, see the `exa_colors(5)` manual page.
|
||||
For more information on the format of these environment variables, see the `zetta_colors(5)` manual page.
|
||||
|
||||
|
||||
EXIT STATUSES
|
||||
|
@ -253,14 +254,14 @@ EXIT STATUSES
|
|||
AUTHOR
|
||||
======
|
||||
|
||||
exa is maintained by Benjamin ‘ogham’ Sago and many other contributors.
|
||||
Zetta is a fork of exa by Benjamin ‘ogham’ Sago and many other contributors.
|
||||
|
||||
**Website:** `https://the.exa.website/` \
|
||||
**Source code:** `https://github.com/ogham/exa` \
|
||||
**Contributors:** `https://github.com/ogham/exa/graphs/contributors`
|
||||
**Exa Website:** `https://the.exa.website/` \
|
||||
**Source code:** `https://github.com/syphar/zetta` \
|
||||
**Contributors:** `https://github.com/syphar/zetta/graphs/contributors`
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
- `exa_colors(5)`
|
||||
- `zetta_colors(5)`
|
|
@ -1,6 +1,6 @@
|
|||
% exa_colors(5) v0.9.0
|
||||
% zetta_colors(5) v0.9.0
|
||||
|
||||
<!-- This is the exa_colors(5) man page, written in Markdown. -->
|
||||
<!-- This is the zetta_colors(5) man page, written in Markdown. -->
|
||||
<!-- To generate the roff version, run `just man`, -->
|
||||
<!-- and the man page will appear in the ‘target’ directory. -->
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
|||
NAME
|
||||
====
|
||||
|
||||
exa_colors — customising the file and UI colours of exa
|
||||
zetta_colors — customising the file and UI colours of zetta
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
The `EXA_COLORS` environment variable can be used to customise the colours that `exa` uses to highlight file names, file metadata, and parts of the UI.
|
||||
The `EXA_COLORS` environment variable can be used to customise the colours that `zetta` uses to highlight file names, file metadata, and parts of the UI.
|
||||
|
||||
You can use the `dircolors` program to generate a script that sets the variable from an input file, or if you don’t mind editing long strings of text, you can just type it out directly. These variables have the following structure:
|
||||
|
||||
|
@ -223,9 +223,9 @@ Values in `EXA_COLORS` override those given in `LS_COLORS`, so you don’t need
|
|||
LIST OF STYLES
|
||||
==============
|
||||
|
||||
Unlike some versions of `ls`, the given ANSI values must be valid colour codes: exa won’t just print out whichever characters are given.
|
||||
Unlike some versions of `ls`, the given ANSI values must be valid colour codes: zetta won’t just print out whichever characters are given.
|
||||
|
||||
The codes accepted by exa are:
|
||||
The codes accepted by zetta are:
|
||||
|
||||
`1`
|
||||
: for bold
|
||||
|
@ -259,8 +259,8 @@ The codes accepted by exa are:
|
|||
|
||||
Many terminals will treat bolded text as a different colour, or at least provide the option to.
|
||||
|
||||
exa provides its own built-in set of file extension mappings that cover a large range of common file extensions, including documents, archives, media, and temporary files.
|
||||
Any mappings in the environment variables will override this default set: running exa with `LS_COLORS="*.zip=32"` will turn zip files green but leave the colours of other compressed files alone.
|
||||
Zetta provides its own built-in set of file extension mappings that cover a large range of common file extensions, including documents, archives, media, and temporary files.
|
||||
Any mappings in the environment variables will override this default set: running zetta with `LS_COLORS="*.zip=32"` will turn zip files green but leave the colours of other compressed files alone.
|
||||
|
||||
You can also disable this built-in set entirely by including a `reset` entry at the beginning of `EXA_COLORS`.
|
||||
So setting `EXA_COLORS="reset:*.txt=31"` will highlight only text files; setting `EXA_COLORS="reset"` will highlight nothing.
|
||||
|
@ -269,14 +269,14 @@ So setting `EXA_COLORS="reset:*.txt=31"` will highlight only text files; setting
|
|||
AUTHOR
|
||||
======
|
||||
|
||||
exa is maintained by Benjamin ‘ogham’ Sago and many other contributors.
|
||||
Zetta is a fork of exa by Benjamin ‘ogham’ Sago maintained by Denis ’syphar’ Cornehl and many other contributors.
|
||||
|
||||
**Website:** `https://the.exa.website/` \
|
||||
**Source code:** `https://github.com/ogham/exa` \
|
||||
**Contributors:** `https://github.com/ogham/exa/graphs/contributors`
|
||||
**Exa Website:** `https://the.exa.website/` \
|
||||
**Source code:** `https://github.com/syphar/zetta` \
|
||||
**Contributors:** `https://github.com/syphar/zetta/graphs/contributors`
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
- `exa(1)`
|
||||
- `zetta(1)`
|
|
@ -52,7 +52,7 @@ pub static ACCESSED: Arg = Arg { short: Some(b'u'), long: "accessed", takes_
|
|||
pub static CREATED: Arg = Arg { short: Some(b'U'), long: "created", takes_value: TakesValue::Forbidden };
|
||||
pub static TIME_STYLE: Arg = Arg { short: None, long: "time-style", takes_value: TakesValue::Necessary(Some(TIME_STYLES)) };
|
||||
const TIMES: Values = &["modified", "changed", "accessed", "created"];
|
||||
const TIME_STYLES: Values = &["default", "long-iso", "full-iso", "iso"];
|
||||
const TIME_STYLES: Values = &["default", "long-iso", "full-iso", "iso", "relative"];
|
||||
|
||||
// suppressing columns
|
||||
pub static NO_PERMISSIONS: Arg = Arg { short: None, long: "no-permissions", takes_value: TakesValue::Forbidden };
|
||||
|
|
|
@ -54,7 +54,7 @@ LONG VIEW OPTIONS
|
|||
-u, --accessed use the accessed timestamp field
|
||||
-U, --created use the created timestamp field
|
||||
--changed use the changed timestamp field
|
||||
--time-style how to format timestamps (default, iso, long-iso, full-iso)
|
||||
--time-style how to format timestamps (default, iso, long-iso, full-iso, relative)
|
||||
--no-permissions suppress the permissions field
|
||||
--octal-permissions list each file's permission in octal format
|
||||
--no-filesize suppress the filesize field
|
||||
|
|
|
@ -254,20 +254,13 @@ impl TimeFormat {
|
|||
}
|
||||
};
|
||||
|
||||
if &word == "default" {
|
||||
Ok(Self::DefaultFormat)
|
||||
}
|
||||
else if &word == "iso" {
|
||||
Ok(Self::ISOFormat)
|
||||
}
|
||||
else if &word == "long-iso" {
|
||||
Ok(Self::LongISO)
|
||||
}
|
||||
else if &word == "full-iso" {
|
||||
Ok(Self::FullISO)
|
||||
}
|
||||
else {
|
||||
Err(OptionsError::BadArgument(&flags::TIME_STYLE, word))
|
||||
match word.to_string_lossy().as_ref() {
|
||||
"default" => Ok(Self::DefaultFormat),
|
||||
"relative" => Ok(Self::Relative),
|
||||
"iso" => Ok(Self::ISOFormat),
|
||||
"long-iso" => Ok(Self::LongISO),
|
||||
"full-iso" => Ok(Self::FullISO),
|
||||
_ => Err(OptionsError::BadArgument(&flags::TIME_STYLE, word))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -464,6 +457,7 @@ mod test {
|
|||
// Individual settings
|
||||
test!(default: TimeFormat <- ["--time-style=default"], None; Both => like Ok(TimeFormat::DefaultFormat));
|
||||
test!(iso: TimeFormat <- ["--time-style", "iso"], None; Both => like Ok(TimeFormat::ISOFormat));
|
||||
test!(relative: TimeFormat <- ["--time-style", "relative"], None; Both => like Ok(TimeFormat::Relative));
|
||||
test!(long_iso: TimeFormat <- ["--time-style=long-iso"], None; Both => like Ok(TimeFormat::LongISO));
|
||||
test!(full_iso: TimeFormat <- ["--time-style", "full-iso"], None; Both => like Ok(TimeFormat::FullISO));
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ impl Column {
|
|||
Self::HardLinks |
|
||||
Self::Inode |
|
||||
Self::Blocks |
|
||||
Self::Timestamp(_) |
|
||||
Self::GitStatus => Alignment::Right,
|
||||
_ => Alignment::Left,
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
//! Timestamp formatting.
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::convert::TryInto;
|
||||
use std::cmp::max;
|
||||
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||
|
||||
use datetime::{LocalDateTime, TimeZone, DatePiece, TimePiece};
|
||||
use datetime::{LocalDateTime, TimeZone, DatePiece, TimePiece, Instant};
|
||||
use datetime::fmt::DateFormat;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -46,6 +48,9 @@ pub enum TimeFormat {
|
|||
/// millisecond and includes its offset down to the minute. This too uses
|
||||
/// only numbers so doesn’t require any special consideration.
|
||||
FullISO,
|
||||
|
||||
/// Use a relative but fixed width representation.
|
||||
Relative,
|
||||
}
|
||||
|
||||
// There are two different formatting functions because local and zoned
|
||||
|
@ -58,6 +63,7 @@ impl TimeFormat {
|
|||
Self::ISOFormat => iso_local(time),
|
||||
Self::LongISO => long_local(time),
|
||||
Self::FullISO => full_local(time),
|
||||
Self::Relative => relative(time),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +73,7 @@ impl TimeFormat {
|
|||
Self::ISOFormat => iso_zoned(time, zone),
|
||||
Self::LongISO => long_zoned(time, zone),
|
||||
Self::FullISO => full_zoned(time, zone),
|
||||
Self::Relative => relative(time),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +120,20 @@ fn long_zoned(time: SystemTime, zone: &TimeZone) -> String {
|
|||
date.hour(), date.minute())
|
||||
}
|
||||
|
||||
#[allow(trivial_numeric_casts)]
|
||||
fn relative(time: SystemTime) -> String {
|
||||
timeago::Formatter::new()
|
||||
.ago("")
|
||||
.convert(
|
||||
Duration::from_secs(
|
||||
max(0, Instant::now().seconds() - systemtime_epoch(time))
|
||||
// this .unwrap is safe since the call above can never result in a
|
||||
// value < 0
|
||||
.try_into().unwrap()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(trivial_numeric_casts)]
|
||||
fn full_local(time: SystemTime) -> String {
|
||||
let date = LocalDateTime::at(systemtime_epoch(time));
|
||||
|
|
|
@ -35,6 +35,13 @@ stderr = { empty = true }
|
|||
status = 0
|
||||
tags = [ 'long', 'time' ]
|
||||
|
||||
[[cmd]]
|
||||
name = "‘exa -l --time-style=relative’ handles dates far past and future dates"
|
||||
shell = "exa -l --time-style=relative /testcases/far-dates"
|
||||
stdout = { file = "outputs/far_dates_relative.ansitxt" }
|
||||
stderr = { empty = true }
|
||||
status = 0
|
||||
tags = [ 'long', 'time' ]
|
||||
|
||||
# alternate date formats
|
||||
|
||||
|
@ -46,6 +53,14 @@ stderr = { empty = true }
|
|||
status = 0
|
||||
tags = [ 'long', 'time-style' ]
|
||||
|
||||
[[cmd]]
|
||||
name = "‘exa -l --time-style=relative’ produces a table using the relative date format"
|
||||
shell = "exa -l --time-style=relative /testcases/dates"
|
||||
stdout = { file = "outputs/dates_long_timestyle_relative.ansitxt" }
|
||||
stderr = { empty = true }
|
||||
status = 0
|
||||
tags = [ 'long', 'time-style' ]
|
||||
|
||||
[[cmd]]
|
||||
name = "‘exa -l --time-style=full-iso’ produces a table using the full-iso date format"
|
||||
shell = "exa -l --time-style=full-iso /testcases/dates"
|
||||
|
|
|
@ -42,7 +42,7 @@ tags = [ 'options' ]
|
|||
name = "exa displays an error for option that takes the wrong parameter"
|
||||
shell = "exa -l --time-style=24"
|
||||
stdout = { empty = true }
|
||||
stderr = { string = "Option --time-style has no \"24\" setting (choices: default, long-iso, full-iso, iso)" }
|
||||
stderr = { string = "Option --time-style has no \"24\" setting (choices: default, long-iso, full-iso, iso, relative)" }
|
||||
status = 3
|
||||
tags = [ 'options' ]
|
||||
|
||||
|
|
3
xtests/outputs/dates_long_timestyle_relative.ansitxt
Normal file
3
xtests/outputs/dates_long_timestyle_relative.ansitxt
Normal file
|
@ -0,0 +1,3 @@
|
|||
.[1;33mr[31mw[0m[38;5;244m-[33mr[31mw[38;5;244m-[33mr[38;5;244m--[0m [1;32m0[0m cassowary [34m15 years[0m peach
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[31mw[38;5;244m-[33mr[38;5;244m--[0m [1;32m0[0m cassowary [34m19 years[0m pear
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[31mw[38;5;244m-[33mr[38;5;244m--[0m [1;32m0[0m cassowary [34m12 years[0m plum
|
2
xtests/outputs/far_dates_relative.ansitxt
Normal file
2
xtests/outputs/far_dates_relative.ansitxt
Normal file
|
@ -0,0 +1,2 @@
|
|||
.rw-rw-r-- 0 vagrant now beyond-the-future
|
||||
.rw-rw-r-- 0 vagrant now the-distant-past
|
|
@ -46,7 +46,7 @@ LONG VIEW OPTIONS
|
|||
-u, --accessed use the accessed timestamp field
|
||||
-U, --created use the created timestamp field
|
||||
--changed use the changed timestamp field
|
||||
--time-style how to format timestamps (default, iso, long-iso, full-iso)
|
||||
--time-style how to format timestamps (default, iso, long-iso, full-iso, relative)
|
||||
--no-permissions suppress the permissions field
|
||||
--octal-permissions list each file's permission in octal format
|
||||
--no-filesize suppress the filesize field
|
||||
|
|
Loading…
Reference in a new issue