diff --git a/src/fs/filter.rs b/src/fs/filter.rs index 39fcb48..8d4f744 100644 --- a/src/fs/filter.rs +++ b/src/fs/filter.rs @@ -191,6 +191,10 @@ pub enum SortField { /// bad, even though that’s kind of nonsensical. So it’s its own variant /// that can be reversed like usual. ModifiedAge, + + /// The file's name, however if the name of the file begins with `.` + /// ignore the leading `.` and then sort as Name + NameMixHidden(SortCase), } /// Whether a field should be sorted case-sensitively or case-insensitively. @@ -253,6 +257,23 @@ impl SortField { Ordering::Equal => natord::compare_ignore_case(&*a.name, &*b.name), order => order, }, + + SortField::NameMixHidden(ABCabc) => natord::compare( + SortField::strip_dot(&a.name), + SortField::strip_dot(&b.name) + ), + SortField::NameMixHidden(AaBbCc) => natord::compare_ignore_case( + SortField::strip_dot(&a.name), + SortField::strip_dot(&b.name) + ) + } + } + + fn strip_dot(n: &str) -> &str { + if n.starts_with(".") { + &n[1..] + } else { + n } } } diff --git a/src/options/filter.rs b/src/options/filter.rs index c22df93..a08e0cd 100644 --- a/src/options/filter.rs +++ b/src/options/filter.rs @@ -41,6 +41,12 @@ impl SortField { else if word == "Name" || word == "Filename" { Ok(SortField::Name(SortCase::ABCabc)) } + else if word == ".name" || word == ".filename" { + Ok(SortField::NameMixHidden(SortCase::AaBbCc)) + } + else if word == ".Name" || word == ".Filename" { + Ok(SortField::NameMixHidden(SortCase::ABCabc)) + } else if word == "size" || word == "filesize" { Ok(SortField::Size) } @@ -231,6 +237,9 @@ mod test { test!(newest: SortField <- ["--sort=oldest"]; Both => Ok(SortField::ModifiedAge)); test!(age: SortField <- ["-sage"]; Both => Ok(SortField::ModifiedAge)); + test!(mix_hidden_lowercase: SortField <- ["--sort", ".name"]; Both => Ok(SortField::NameMixHidden(SortCase::AaBbCc))); + test!(mix_hidden_uppercase: SortField <- ["--sort", ".Name"]; Both => Ok(SortField::NameMixHidden(SortCase::ABCabc))); + // Errors test!(error: SortField <- ["--sort=colour"]; Both => Err(Misfire::BadArgument(&flags::SORT, OsString::from("colour"))));