Browse Source

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”.
Benjamin Sago 8 years ago
parent
commit
c475cccce4
7 changed files with 32 additions and 12 deletions
  1. 1 1
      README.md
  2. 1 1
      contrib/man/exa.1
  3. 13 6
      src/options/filter.rs
  4. 10 1
      src/options/misfire.rs
  5. 2 0
      xtests/error_lt
  6. 1 1
      xtests/error_ltr
  7. 4 2
      xtests/run.sh

+ 1 - 1
README.md

@@ -54,7 +54,7 @@ These options are available when running with --long (`-l`):
 - **--time-style**: how to format timestamps
 - **--time-style**: how to format timestamps
 
 
 - Valid **--color** options are **always**, **automatic**, and **never**.
 - Valid **--color** options are **always**, **automatic**, and **never**.
-- 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**.
+- 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**.
 - Valid time fields are **modified**, **accessed**, and **created**.
 - Valid time fields are **modified**, **accessed**, and **created**.
 - Valid time styles are **default**, **iso**, **long-iso**, and **full-iso**.
 - Valid time styles are **default**, **iso**, **long-iso**, and **full-iso**.
 
 

+ 1 - 1
contrib/man/exa.1

@@ -77,7 +77,7 @@ reverse the sort order
 .B \-s, \-\-sort=\f[I]SORT_FIELD\f[]
 .B \-s, \-\-sort=\f[I]SORT_FIELD\f[]
 which field to sort by.
 which field to sort by.
 Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, type, and none.
 Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, type, and none.
-The modified field has the aliases date, time, and oldest, and its reverse order has the aliases age and newest.
+The modified field has the aliases date, time, and newest, and its reverse order has the aliases age and oldest.
 Fields starting with a capital letter will sort uppercase before lowercase: 'A' then 'B' then 'a' then 'b'.
 Fields starting with a capital letter will sort uppercase before lowercase: 'A' then 'B' then 'a' then 'b'.
 Fields starting with a lowercase letter will mix them: 'A' then 'a' then 'B' then 'b'.
 Fields starting with a lowercase letter will mix them: 'A' then 'a' then 'B' then 'b'.
 .RS
 .RS

+ 13 - 6
src/options/filter.rs

@@ -49,10 +49,17 @@ impl SortField {
         else if word == "Ext" || word == "Extension" {
         else if word == "Ext" || word == "Extension" {
             Ok(SortField::Extension(SortCase::ABCabc))
             Ok(SortField::Extension(SortCase::ABCabc))
         }
         }
-        else if word == "date" || word == "time" || word == "mod" || word == "modified" || word == "old" || word == "oldest" {
+        else if word == "date" || word == "time" || word == "mod" || word == "modified" || word == "new" || word == "newest" {
+            // “new” sorts oldest at the top and newest at the bottom; “old”
+            // sorts newest at the top and oldest at the bottom. I think this
+            // is the right way round to do this: “size” puts the smallest at
+            // the top and the largest at the bottom, doesn’t it?
             Ok(SortField::ModifiedDate)
             Ok(SortField::ModifiedDate)
         }
         }
-        else if word == "age" || word == "new" || word == "newest" {
+        else if word == "age" || word == "old" || word == "oldest" {
+            // Similarly, “age” means that files with the least age (the
+            // newest files) get sorted at the top, and files with the most
+            // age (the oldest) at the bottom.
             Ok(SortField::ModifiedAge)
             Ok(SortField::ModifiedAge)
         }
         }
         else if word == "acc" || word == "accessed" {
         else if word == "acc" || word == "accessed" {
@@ -209,10 +216,10 @@ mod test {
         test!(one_short:     SortField <- ["-saccessed"];      Both => Ok(SortField::AccessedDate));
         test!(one_short:     SortField <- ["-saccessed"];      Both => Ok(SortField::AccessedDate));
         test!(lowercase:     SortField <- ["--sort", "name"];  Both => Ok(SortField::Name(SortCase::AaBbCc)));
         test!(lowercase:     SortField <- ["--sort", "name"];  Both => Ok(SortField::Name(SortCase::AaBbCc)));
         test!(uppercase:     SortField <- ["--sort", "Name"];  Both => Ok(SortField::Name(SortCase::ABCabc)));
         test!(uppercase:     SortField <- ["--sort", "Name"];  Both => Ok(SortField::Name(SortCase::ABCabc)));
-        test!(old:           SortField <- ["--sort", "old"];   Both => Ok(SortField::ModifiedDate));
-        test!(oldest:        SortField <- ["--sort=oldest"];   Both => Ok(SortField::ModifiedDate));
-        test!(new:           SortField <- ["--sort", "new"];   Both => Ok(SortField::ModifiedAge));
-        test!(newest:        SortField <- ["--sort=newest"];   Both => Ok(SortField::ModifiedAge));
+        test!(old:           SortField <- ["--sort", "new"];   Both => Ok(SortField::ModifiedDate));
+        test!(oldest:        SortField <- ["--sort=newest"];   Both => Ok(SortField::ModifiedDate));
+        test!(new:           SortField <- ["--sort", "old"];   Both => Ok(SortField::ModifiedAge));
+        test!(newest:        SortField <- ["--sort=oldest"];   Both => Ok(SortField::ModifiedAge));
         test!(age:           SortField <- ["-sage"];           Both => Ok(SortField::ModifiedAge));
         test!(age:           SortField <- ["-sage"];           Both => Ok(SortField::ModifiedAge));
 
 
         // Errors
         // Errors

+ 10 - 1
src/options/misfire.rs

@@ -113,10 +113,19 @@ impl fmt::Display for ParseError {
 }
 }
 
 
 impl Misfire {
 impl Misfire {
+    /// Try to second-guess what the user was trying to do, depending on what
+    /// went wrong.
     pub fn suggestion(&self) -> Option<&'static str> {
     pub fn suggestion(&self) -> Option<&'static str> {
+        // ‘ls -lt’ and ‘ls -ltr’ are common combinations
         if let Misfire::BadArgument(ref time, ref r) = *self {
         if let Misfire::BadArgument(ref time, ref r) = *self {
             if *time == &flags::TIME && r == "r" {
             if *time == &flags::TIME && r == "r" {
-                return Some("To sort newest files first, try \"--sort modified\", or just \"-stime\"");
+                return Some("To sort oldest files last, try \"--sort oldest\", or just \"-sold\"");
+            }
+        }
+
+        if let Misfire::InvalidOptions(ParseError::NeedsValue { ref flag, values: _ }) = *self {
+            if *flag == Flag::Short(b't') {
+                return Some("To sort newest files last, try \"--sort newest\", or just \"-snew\"");
             }
             }
         }
         }
 
 

+ 2 - 0
xtests/error_lt

@@ -0,0 +1,2 @@
+Flag -t needs a value (choices: modified, accessed, created)
+To sort newest files last, try "--sort newest", or just "-snew"

+ 1 - 1
xtests/error_ltr

@@ -1,2 +1,2 @@
 Option --time (-t) has no "r" setting (choices: modified, accessed, created)
 Option --time (-t) has no "r" setting (choices: modified, accessed, created)
-To sort newest files first, try "--sort modified", or just "-stime"
+To sort oldest files last, try "--sort oldest", or just "-sold"

+ 4 - 2
xtests/run.sh

@@ -143,8 +143,9 @@ $exa $testcases/file-names-exts/music.* -I "*.OGG|*.mp3" -1 2>&1 | diff -q - $re
 # Dates and times
 # Dates and times
 $exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/dates_accessed  || exit 1
 $exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/dates_accessed  || exit 1
 $exa $testcases/dates -lh            --sort=modified 2>&1 | diff -q - $results/dates_modified  || exit 1
 $exa $testcases/dates -lh            --sort=modified 2>&1 | diff -q - $results/dates_modified  || exit 1
-$exa $testcases/dates -lh         -r --sort=newest   2>&1 | diff -q - $results/dates_modified  || exit 1
-$exa $testcases/dates -lh            --sort=newest   2>&1 | diff -q - $results/dates_deifidom  || exit 1
+$exa $testcases/dates -lh            --sort=newest   2>&1 | diff -q - $results/dates_modified  || exit 1
+$exa $testcases/dates -lh         -r --sort=newest   2>&1 | diff -q - $results/dates_deifidom  || exit 1
+$exa $testcases/dates -lh            --sort=oldest   2>&1 | diff -q - $results/dates_deifidom  || exit 1
 $exa $testcases/dates -l       --time-style=long-iso 2>&1 | diff -q - $results/dates_long_iso  || exit 1
 $exa $testcases/dates -l       --time-style=long-iso 2>&1 | diff -q - $results/dates_long_iso  || exit 1
 $exa $testcases/dates -l       --time-style=full-iso 2>&1 | diff -q - $results/dates_full_iso  || exit 1
 $exa $testcases/dates -l       --time-style=full-iso 2>&1 | diff -q - $results/dates_full_iso  || exit 1
 $exa $testcases/dates -l       --time-style=iso      2>&1 | diff -q - $results/dates_iso       || exit 1
 $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
 
 
 # Error suggestions
 # Error suggestions
 $exa -ltr 2>&1 | diff -q - $results/error_ltr  || exit 1
 $exa -ltr 2>&1 | diff -q - $results/error_ltr  || exit 1
+$exa -lt  2>&1 | diff -q - $results/error_lt   || exit 1
 
 
 
 
 # Debug mode
 # Debug mode