Skip to content

Commit eaece8c

Browse files
authored
Merge branch 'master' into customize-size-scale-colours
2 parents 3ef6195 + 6d8f690 commit eaece8c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+718
-439
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ ubuntu-xenial-16.04-cloudimg-console.log
1313
/exa-macos-x86_64-*.zip
1414
/MD5SUMS
1515
/SHA1SUMS
16+
17+
# Snap stuff
18+
parts
19+
prime
20+
stage
21+
*.snap

Cargo.lock

Lines changed: 80 additions & 98 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ name = "exa"
33
version = "0.9.0"
44
authors = [ "Benjamin Sago <ogham@bsago.me>" ]
55
build = "build.rs"
6+
edition = "2018"
67

78
description = "A modern replacement for ls"
89
homepage = "https://the.exa.website/"
@@ -63,3 +64,18 @@ opt-level = 3
6364
debug = false
6465
lto = true
6566
panic = "abort"
67+
68+
69+
[package.metadata.deb]
70+
license-file = [ "LICENCE" ]
71+
depends = "$auto"
72+
extended-description = """
73+
exa is a replacement for ls written in Rust.
74+
"""
75+
section = "utils"
76+
priority = "optional"
77+
assets = [
78+
[ "target/release/exa", "/usr/bin/exa", "0755" ],
79+
[ "contrib/man/exa.1", "/usr/share/man/man1/exa.1", "0644" ],
80+
[ "contrib/completions.bash", "/etc/bash_completion.d/exa", "0644" ],
81+
]

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
## Rationale
66

7-
**exa** is a modern replacement for the command-line program ls that ships with Unix and Linux operating systems, with 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**.
7+
**exa** is a modern replacement for the command-line program `ls` that ships with Unix and Linux operating systems, with 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**.
88

9-
By deliberately making some decisions differently, exa attempts to be a more featureful, more user-friendly version of ls.
9+
By deliberately making some decisions differently, exa attempts to be a more featureful, more user-friendly version of `ls`.
1010

1111
## Screenshots
1212

@@ -25,8 +25,10 @@ exa’s options are almost, but not quite, entirely unlike `ls`'s.
2525
- **-R**, **--recurse**: recurse into directories
2626
- **-T**, **--tree**: recurse into directories as a tree
2727
- **-x**, **--across**: sort the grid across, rather than downwards
28+
- **-F**, **--classify**: display type indicator by file names
2829
- **--colo[u]r**: when to use terminal colours
2930
- **--colo[u]r-scale**: highlight levels of file sizes distinctly
31+
- **--icons**: display icons
3032

3133
### Filtering Options
3234

@@ -58,8 +60,13 @@ These options are available when running with --long (`-l`):
5860
- **-u**, **--accessed**: use the accessed timestamp field
5961
- **-U**, **--created**: use the created timestamp field
6062
- **-@**, **--extended**: list each file's extended attributes and sizes
63+
- **--changed**: use the changed timestamp field
6164
- **--git**: list each file's Git status, if tracked or ignored
6265
- **--time-style**: how to format timestamps
66+
- **--no-permissions**: suppress the permissions field
67+
- **--no-filesize**: suppress the filesize field
68+
- **--no-user**: suppress the user field
69+
- **--no-time**: suppress the time field
6370

6471
- Valid **--color** options are **always**, **automatic**, and **never**.
6572
- 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**.
@@ -69,7 +76,7 @@ These options are available when running with --long (`-l`):
6976

7077
## Installation
7178

72-
exa is written in [Rust](http://www.rust-lang.org). You will need rustc version 1.17.0 or higher. The recommended way to install Rust is from the official download page.
79+
exa is written in [Rust](http://www.rust-lang.org). You will need rustc version 1.35.0 or higher. The recommended way to install Rust is from the official download page.
7380
Once you have it set up, a simple `make install` will compile exa and install it into `/usr/local/bin`.
7481

7582
exa depends on [libgit2](https://github.com/alexcrichton/git2-rs) for certain features.
@@ -101,6 +108,12 @@ or:
101108

102109
[Formulae](https://github.com/Homebrew/homebrew-core/blob/master/Formula/exa.rb)
103110

111+
### Fedora
112+
113+
You can install the `exa` package from the official Fedora repositories by running:
114+
115+
dnf install exa
116+
104117
### Nix
105118

106119
`exa` is also installable through [the derivation](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/exa/default.nix) using the [nix package manager](https://nixos.org/nix/) by running:

Vagrantfile

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ Vagrant.configure(2) do |config|
44

55
# We use Ubuntu instead of Debian because the image comes with two-way
66
# shared folder support by default.
7-
UBUNTU = 'ubuntu/xenial64'
7+
UBUNTU = 'bento/ubuntu-16.04'
88

99
# The main VM is the one used for development and testing.
1010
config.vm.define(:exa, primary: true) do |config|
1111
config.vm.provider :virtualbox do |v|
1212
v.name = 'exa'
13-
v.memory = 1024
14-
v.cpus = 1
13+
v.memory = 2048
14+
v.cpus = 2
15+
end
16+
17+
config.vm.provider :vmware_desktop do |v|
18+
v.vmx['memsize'] = '2048'
19+
v.vmx['numvcpus'] = '2'
1520
end
1621

1722
config.vm.box = UBUNTU
@@ -484,6 +489,21 @@ Vagrant.configure(2) do |config|
484489
sudo chown #{user}:#{user} -R "#{test_dir}/git2"
485490
EOF
486491

492+
# A third Git repository
493+
# Regression test for https://github.com/ogham/exa/issues/526
494+
config.vm.provision :shell, privileged: false, inline: <<-EOF
495+
set -xe
496+
mkdir -p "#{test_dir}/git3"
497+
cd "#{test_dir}/git3"
498+
git init
499+
500+
# Create a symbolic link pointing to a non-existing file
501+
ln -s aaa/aaa/a b
502+
503+
find "#{test_dir}/git3" -exec touch {} -t #{some_date} \\;
504+
sudo chown #{user}:#{user} -R "#{test_dir}/git3"
505+
EOF
506+
487507
# Hidden and dot file testcases.
488508
# We need to set the permissions of `.` and `..` because they actually
489509
# get displayed in the output here, so this has to come last.

contrib/completions.fish

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#!/bin/sh
21
# Meta-stuff
32
complete -c exa -s 'v' -l 'version' -d "Show version of exa"
43
complete -c exa -s '?' -l 'help' -d "Show list of command-line options"
@@ -49,6 +48,7 @@ complete -c exa -s 's' -l 'sort' -x -d "Which field to sort by" -a "
4948
"
5049

5150
complete -c exa -s 'I' -l 'ignore-glob' -d "Ignore files that match these glob patterns" -r
51+
complete -c exa -s 'D' -l 'only-dirs' -d "List only directories"
5252

5353
# Long view options
5454
complete -c exa -s 'b' -l 'binary' -d "List file sizes with binary prefixes"
@@ -74,7 +74,11 @@ complete -c exa -l 'time-style' -x -d "How to format timestamps" -a "
7474
long-iso\t'Display longer ISO timestaps, up to the minute'
7575
full-iso\t'Display full ISO timestamps, up to the nanosecond'
7676
"
77+
complete -c exa -l 'no-permissions' -d "Suppress the permissions field"
78+
complete -c exa -l 'no-filesize' -d "Suppress the filesize field"
79+
complete -c exa -l 'no-user' -d "Suppress the user field"
80+
complete -c exa -l 'no-time' -d "Suppress the time field"
7781

7882
# Optional extras
79-
complete -c exa -s 'g' -l 'git' -d "List each file's Git status, if tracked"
83+
complete -c exa -l 'git' -d "List each file's Git status, if tracked"
8084
complete -c exa -s '@' -l 'extended' -d "List each file's extended attributes and sizes"

contrib/completions.zsh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ __exa() {
2626
--git-ignore"[Ignore files mentioned in '.gitignore']" \
2727
{-a,--all}"[Show hidden and 'dot' files]" \
2828
{-d,--list-dirs}"[List directories like regular files]" \
29+
{-D,--only-dirs}"[List only directories]" \
2930
{-L,--level}"+[Limit the depth of recursion]" \
3031
{-r,--reverse}"[Reverse the sort order]" \
3132
{-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)" \
3233
{-I,--ignore-glob}"[Ignore files that match these glob patterns]" \
3334
{-b,--binary}"[List file sizes with binary prefixes]" \
3435
{-B,--bytes}"[List file sizes in bytes, without any prefixes]" \
36+
--changed"[Use the changed timestamp field]" \
3537
{-g,--group}"[List each file's group]" \
3638
{-h,--header}"[Add a header row to each column]" \
3739
{-H,--links}"[List each file's number of hard links]" \
@@ -40,6 +42,10 @@ __exa() {
4042
{-S,--blocks}"[List each file's number of filesystem blocks]" \
4143
{-t,--time}="[Which time field to show]:(time field):(accessed changed created modified)" \
4244
--time-style="[How to format timestamps]:(time style):(default iso long-iso full-iso)" \
45+
--no-permissions"[Suppress the permissions field]" \
46+
--no-filesize"[Suppress the filesize field]" \
47+
--no-user"[Suppress the user field]" \
48+
--no-time"[Suppress the time field]" \
4349
{-u,--accessed}"[Use the accessed timestamp field]" \
4450
{-U,--created}"[Use the created timestamp field]" \
4551
--git"[List each file's Git status, if tracked]" \

contrib/man/exa.1

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ list file sizes in bytes, without any prefixes
132132
.RS
133133
.RE
134134
.TP
135+
.B \-\-changed
136+
use the changed timestamp field
137+
.RS
138+
.RE
139+
.TP
135140
.B \-g, \-\-group
136141
list each file\[aq]s group
137142
.RS
@@ -182,6 +187,26 @@ use the created timestamp field
182187
.RS
183188
.RE
184189
.TP
190+
.B \-\-no\-permissions
191+
suppress the permissions field
192+
.RS
193+
.RE
194+
.TP
195+
.B \-\-no\-filesize
196+
suppress the filesize field
197+
.RS
198+
.RE
199+
.TP
200+
.B \-\-no\-user
201+
suppress the user field
202+
.RS
203+
.RE
204+
.TP
205+
.B \-\-no\-time
206+
suppress the time field
207+
.RS
208+
.RE
209+
.TP
185210
.B \-\@, \-\-extended
186211
list each file\[aq]s extended attributes and sizes
187212
.RS

snap/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.snapcraft

snap/snapcraft.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: exa
2+
version: 'latest'
3+
summary: Replacement for 'ls' written in Rust
4+
description: |
5+
It uses colours for information by default, helping you distinguish between
6+
many types of files, such as whether you are the owner, or in the owning
7+
group. It also has extra features not present in the original ls, such as
8+
viewing the Git status for a directory, or recursing into directories with a
9+
tree view. exa is written in Rust, so it’s small, fast, and portable.
10+
11+
grade: stable
12+
confinement: classic
13+
14+
apps:
15+
exa:
16+
command: exa
17+
18+
parts:
19+
exa:
20+
plugin: rust
21+
source: .
22+
stage-packages:
23+
- libgit2-24
24+
- cmake
25+
- libz-dev

src/exa.rs

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,22 @@
11
#![warn(trivial_casts, trivial_numeric_casts)]
22
#![warn(unused_results)]
33

4-
extern crate ansi_term;
5-
extern crate datetime;
6-
extern crate glob;
7-
extern crate libc;
8-
extern crate locale;
9-
extern crate natord;
10-
extern crate num_cpus;
11-
extern crate number_prefix;
12-
extern crate scoped_threadpool;
13-
extern crate term_grid;
14-
extern crate unicode_width;
15-
extern crate users;
16-
extern crate zoneinfo_compiled;
17-
extern crate term_size;
18-
19-
#[cfg(feature="git")] extern crate git2;
20-
21-
#[macro_use] extern crate lazy_static;
22-
#[macro_use] extern crate log;
23-
24-
254
use std::env::var_os;
265
use std::ffi::{OsStr, OsString};
276
use std::io::{stderr, Write, Result as IOResult};
287
use std::path::{Component, PathBuf};
298

309
use ansi_term::{ANSIStrings, Style};
3110

32-
use fs::{Dir, File};
33-
use fs::feature::ignore::IgnoreCache;
34-
use fs::feature::git::GitCache;
35-
use options::{Options, Vars};
36-
pub use options::vars;
37-
pub use options::Misfire;
38-
use output::{escape, lines, grid, grid_details, details, View, Mode};
11+
use log::debug;
12+
13+
use crate::fs::{Dir, File};
14+
use crate::fs::feature::ignore::IgnoreCache;
15+
use crate::fs::feature::git::GitCache;
16+
use crate::options::{Options, Vars};
17+
pub use crate::options::vars;
18+
pub use crate::options::Misfire;
19+
use crate::output::{escape, lines, grid, grid_details, details, View, Mode};
3920

4021
mod fs;
4122
mod info;
@@ -91,7 +72,7 @@ fn git_options(options: &Options, args: &[&OsStr]) -> Option<GitCache> {
9172
}
9273

9374
fn ignore_cache(options: &Options) -> Option<IgnoreCache> {
94-
use fs::filter::GitIgnore;
75+
use crate::fs::filter::GitIgnore;
9576

9677
match options.filter.git_ignore {
9778
GitIgnore::CheckAndIgnore => Some(IgnoreCache::new()),

src/fs/dir.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use std::fs;
33
use std::path::{Path, PathBuf};
44
use std::slice::Iter as SliceIter;
55

6-
use fs::File;
7-
use fs::feature::ignore::IgnoreCache;
6+
use log::info;
7+
8+
use crate::fs::File;
9+
use crate::fs::feature::ignore::IgnoreCache;
810

911

1012
/// A **Dir** provides a cached list of the file paths in a directory that's

src/fs/feature/git.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use std::path::{Path, PathBuf};
44
use std::sync::Mutex;
55

66
use git2;
7+
use log::{debug, error, info, warn};
78

8-
use fs::fields as f;
9+
use crate::fs::fields as f;
910

1011

1112
/// A **Git cache** is assembled based on the user’s input arguments.
@@ -265,11 +266,11 @@ impl Git {
265266
fn reorient(path: &Path) -> PathBuf {
266267
use std::env::current_dir;
267268
// I’m not 100% on this func tbh
268-
match current_dir() {
269+
let path = match current_dir() {
269270
Err(_) => Path::new(".").join(&path),
270271
Ok(dir) => dir.join(&path),
271-
}.canonicalize().unwrap() // errors can be ignored here because they only occur if
272-
// the path does not exist / a component is not a folder
272+
};
273+
path.canonicalize().unwrap_or(path)
273274
}
274275

275276
/// The character to display if the file has been modified, but not staged.

src/fs/feature/ignore.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use std::io::Read;
88
use std::path::{Path, PathBuf};
99
use std::sync::RwLock;
1010

11-
use fs::filter::IgnorePatterns;
11+
use log::debug;
12+
13+
use crate::fs::filter::IgnorePatterns;
1214

1315

1416
/// An **ignore cache** holds sets of glob patterns paired with the

src/fs/feature/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub mod git {
88
use std::iter::FromIterator;
99
use std::path::{Path, PathBuf};
1010

11-
use fs::fields as f;
11+
use crate::fs::fields as f;
1212

1313

1414
pub struct GitCache;

0 commit comments

Comments
 (0)