Skip to content

Commit c475ccc

Browse files
committed
Flip the new/old order, and add suggestion for -lt
I changed my mind about which way round sorting by “newest” or by “oldest” should actually go. If you’re listing a large directory, you see the last lines of the output first, so these files should be the ones with the largest whatever the sort field is. It’s about sorting *last*, not sorting *first*. Sorting by size wouldn’t say “sorts smallest files first”, it would say “sorts largest files last”. Right? Also, add a new suggestion that warns against “ls -lt”.
1 parent a8bf990 commit c475ccc

File tree

7 files changed

+32
-12
lines changed

7 files changed

+32
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ These options are available when running with --long (`-l`):
5454
- **--time-style**: how to format timestamps
5555

5656
- Valid **--color** options are **always**, **automatic**, and **never**.
57-
- Valid sort fields are **accessed**, **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 **oldest**, while its reverse has the aliases **age** and **newest**.
57+
- Valid sort fields are **accessed**, **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**.
5858
- Valid time fields are **modified**, **accessed**, and **created**.
5959
- Valid time styles are **default**, **iso**, **long-iso**, and **full-iso**.
6060

contrib/man/exa.1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ reverse the sort order
7777
.B \-s, \-\-sort=\f[I]SORT_FIELD\f[]
7878
which field to sort by.
7979
Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, type, and none.
80-
The modified field has the aliases date, time, and oldest, and its reverse order has the aliases age and newest.
80+
The modified field has the aliases date, time, and newest, and its reverse order has the aliases age and oldest.
8181
Fields starting with a capital letter will sort uppercase before lowercase: 'A' then 'B' then 'a' then 'b'.
8282
Fields starting with a lowercase letter will mix them: 'A' then 'a' then 'B' then 'b'.
8383
.RS

src/options/filter.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,17 @@ impl SortField {
4949
else if word == "Ext" || word == "Extension" {
5050
Ok(SortField::Extension(SortCase::ABCabc))
5151
}
52-
else if word == "date" || word == "time" || word == "mod" || word == "modified" || word == "old" || word == "oldest" {
52+
else if word == "date" || word == "time" || word == "mod" || word == "modified" || word == "new" || word == "newest" {
53+
// “new” sorts oldest at the top and newest at the bottom; “old”
54+
// sorts newest at the top and oldest at the bottom. I think this
55+
// is the right way round to do this: “size” puts the smallest at
56+
// the top and the largest at the bottom, doesn’t it?
5357
Ok(SortField::ModifiedDate)
5458
}
55-
else if word == "age" || word == "new" || word == "newest" {
59+
else if word == "age" || word == "old" || word == "oldest" {
60+
// Similarly, “age” means that files with the least age (the
61+
// newest files) get sorted at the top, and files with the most
62+
// age (the oldest) at the bottom.
5663
Ok(SortField::ModifiedAge)
5764
}
5865
else if word == "acc" || word == "accessed" {
@@ -209,10 +216,10 @@ mod test {
209216
test!(one_short: SortField <- ["-saccessed"]; Both => Ok(SortField::AccessedDate));
210217
test!(lowercase: SortField <- ["--sort", "name"]; Both => Ok(SortField::Name(SortCase::AaBbCc)));
211218
test!(uppercase: SortField <- ["--sort", "Name"]; Both => Ok(SortField::Name(SortCase::ABCabc)));
212-
test!(old: SortField <- ["--sort", "old"]; Both => Ok(SortField::ModifiedDate));
213-
test!(oldest: SortField <- ["--sort=oldest"]; Both => Ok(SortField::ModifiedDate));
214-
test!(new: SortField <- ["--sort", "new"]; Both => Ok(SortField::ModifiedAge));
215-
test!(newest: SortField <- ["--sort=newest"]; Both => Ok(SortField::ModifiedAge));
219+
test!(old: SortField <- ["--sort", "new"]; Both => Ok(SortField::ModifiedDate));
220+
test!(oldest: SortField <- ["--sort=newest"]; Both => Ok(SortField::ModifiedDate));
221+
test!(new: SortField <- ["--sort", "old"]; Both => Ok(SortField::ModifiedAge));
222+
test!(newest: SortField <- ["--sort=oldest"]; Both => Ok(SortField::ModifiedAge));
216223
test!(age: SortField <- ["-sage"]; Both => Ok(SortField::ModifiedAge));
217224

218225
// Errors

src/options/misfire.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,19 @@ impl fmt::Display for ParseError {
113113
}
114114

115115
impl Misfire {
116+
/// Try to second-guess what the user was trying to do, depending on what
117+
/// went wrong.
116118
pub fn suggestion(&self) -> Option<&'static str> {
119+
// ‘ls -lt’ and ‘ls -ltr’ are common combinations
117120
if let Misfire::BadArgument(ref time, ref r) = *self {
118121
if *time == &flags::TIME && r == "r" {
119-
return Some("To sort newest files first, try \"--sort modified\", or just \"-stime\"");
122+
return Some("To sort oldest files last, try \"--sort oldest\", or just \"-sold\"");
123+
}
124+
}
125+
126+
if let Misfire::InvalidOptions(ParseError::NeedsValue { ref flag, values: _ }) = *self {
127+
if *flag == Flag::Short(b't') {
128+
return Some("To sort newest files last, try \"--sort newest\", or just \"-snew\"");
120129
}
121130
}
122131

xtests/error_lt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flag -t needs a value (choices: modified, accessed, created)
2+
To sort newest files last, try "--sort newest", or just "-snew"

xtests/error_ltr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Option --time (-t) has no "r" setting (choices: modified, accessed, created)
2-
To sort newest files first, try "--sort modified", or just "-stime"
2+
To sort oldest files last, try "--sort oldest", or just "-sold"

xtests/run.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ $exa $testcases/file-names-exts/music.* -I "*.OGG|*.mp3" -1 2>&1 | diff -q - $re
143143
# Dates and times
144144
$exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/dates_accessed || exit 1
145145
$exa $testcases/dates -lh --sort=modified 2>&1 | diff -q - $results/dates_modified || exit 1
146-
$exa $testcases/dates -lh -r --sort=newest 2>&1 | diff -q - $results/dates_modified || exit 1
147-
$exa $testcases/dates -lh --sort=newest 2>&1 | diff -q - $results/dates_deifidom || exit 1
146+
$exa $testcases/dates -lh --sort=newest 2>&1 | diff -q - $results/dates_modified || exit 1
147+
$exa $testcases/dates -lh -r --sort=newest 2>&1 | diff -q - $results/dates_deifidom || exit 1
148+
$exa $testcases/dates -lh --sort=oldest 2>&1 | diff -q - $results/dates_deifidom || exit 1
148149
$exa $testcases/dates -l --time-style=long-iso 2>&1 | diff -q - $results/dates_long_iso || exit 1
149150
$exa $testcases/dates -l --time-style=full-iso 2>&1 | diff -q - $results/dates_full_iso || exit 1
150151
$exa $testcases/dates -l --time-style=iso 2>&1 | diff -q - $results/dates_iso || exit 1
@@ -265,6 +266,7 @@ $exa -l --time-style=24 2>&1 | diff -q - $results/error_setting || exit 1
265266

266267
# Error suggestions
267268
$exa -ltr 2>&1 | diff -q - $results/error_ltr || exit 1
269+
$exa -lt 2>&1 | diff -q - $results/error_lt || exit 1
268270

269271

270272
# Debug mode

0 commit comments

Comments
 (0)